package internal

import (
	"bytes"
	crand "crypto/rand"
	"encoding/binary"
	"encoding/hex"
	"math/rand"
	"strings"
	"sync"
)

type RandomIDGenerator struct {
	sync.Mutex
	randSource *rand.Rand
}

var randomIDGenerator *RandomIDGenerator

func init() {
	randomIDGenerator = &RandomIDGenerator{}
	var rngSeed int64
	_ = binary.Read(crand.Reader, binary.LittleEndian, &rngSeed)
	randomIDGenerator.randSource = rand.New(rand.NewSource(rngSeed))
}

func NewIDs() ([16]byte, [8]byte) {
	randomIDGenerator.Lock()
	defer randomIDGenerator.Unlock()
	tid := [16]byte{}
	randomIDGenerator.randSource.Read(tid[:])
	sid := [8]byte{}
	randomIDGenerator.randSource.Read(sid[:])
	return tid, sid
}

func JoinStrings(strings []string, separator string) string {
	var buffer bytes.Buffer
	lenStr := len(strings)
	for index, value := range strings {
		if index < lenStr-1 {
			buffer.WriteString(value)
			buffer.WriteString(separator)
		} else {
			buffer.WriteString(value)
		}
	}
	return buffer.String()
}

// GetSpanIDFromOneapm guid必须是16位字符串，否则返回0
func GetSpanIDFromOneapm(guid string) ([8]byte, error) {
	var spanID [8]byte
	if len(guid) < 16 {
		guid = strings.Repeat("0", 16-len(guid)) + guid
	}
	temp, err := hex.DecodeString(guid)
	if nil != err || len(temp) != 8 {
		return spanID, err
	}
	byteArrIndex := 0
	for _, v := range temp {
		spanID[byteArrIndex] = v
		byteArrIndex++
	}
	//fmt.Println("guid", guid, "spanID", spanID)
	return spanID, nil
}

func GetTraceIDFromOneapm(traceID string) ([16]byte, error) {
	var traceIDOT [16]byte
	if len(traceID) < 16 {
		traceID = strings.Repeat("0", 16-len(traceID)) + traceID
	}
	temp, err := hex.DecodeString(traceID)
	if nil != err || len(temp) != 8 {
		return traceIDOT, err
	}
	byteArrIndex := 0
	for _, v := range temp {
		traceIDOT[byteArrIndex] = v
		byteArrIndex++
	}
	//fmt.Println("traceID", traceID, "traceIDOT", traceIDOT)
	return traceIDOT, nil
}
